import pygame 
from settings import *
from support import import_folder
from entity import Entity

class Player(Entity):
	def __init__(self,pos,groups,obstacle_sprites,create_attack,destroy_attack,create_magic):
		super().__init__(groups)
		#加载图片，并确保图像支持透明度
		self.image = pygame.image.load('../graphics/test/player.png').convert_alpha() 
		#获取图像的矩形区域
		self.rect = self.image.get_rect(topleft = pos)
		#创建一个矩形，比原始矩形小26像素，以便在碰撞检测中排除头部
		self.hitbox = self.rect.inflate(-6,HITBOX_OFFSET['player'])

		#加载动画图片
		self.import_player_assets()
	 	#设置初始状态
		self.status = 'down'
  
		#当前是否处于攻击状态
		self.attacking = False
		#设置攻击冷却时间,即400毫秒
		self.attack_cooldown = 400
		#设置攻击时间
		self.attack_time = None

		#保存障碍物精灵组
		self.obstacle_sprites = obstacle_sprites
  
		#创建武器精灵
		self.create_attack = create_attack
		#销毁武器精灵
		self.destroy_attack = destroy_attack
		#当前使用的武器索引值
		self.weapon_index = 0
		#当前使用的武器
		self.weapon = list(weapon_data.keys())[self.weapon_index]
		#是否可以切换武器
		self.can_switch_weapon = True
		#保存上一次武器切换的时间
		self.weapon_switch_time = None
		#武器切换冷却时间
		self.switch_duration_cooldown = 200

		#魔法攻击
		self.create_magic = create_magic
		#当前使用技能索引
		self.magic_index = 0
		#当前使用的技能
		self.magic = list(magic_data.keys())[self.magic_index]
		#是否可以切换技能
		self.can_switch_magic = True
		#保存上一次技能切换的时间
		self.magic_switch_time = None

		#初始化玩家的属性
		self.stats = {'health':100, 'energy':60, 'speed':5, 'attack':10, 'magic':4}
		#设置属性最大值
		self.max_stats = {'health': 300, 'energy': 140, 'attack': 20, 'magic' : 10, 'speed': 10}
		#升级所需的经验值
		self.upgrade_cost = {'health': 100, 'energy': 100, 'attack': 100, 'magic' : 100, 'speed': 100}
		self.health = self.stats['health'] * 0.5 # 玩家当前的生命值
		self.energy = self.stats['energy'] * 0.8 # 玩家当前的能量值
		#设置移动速度
		self.speed = self.stats['speed']
		#经验值
		self.exp = 123

		#玩家当前是否可以被击中
		self.vulnerable = True
		#玩家上一次被击中时间
		self.hurt_time = None
		#玩家无敌时间
		self.invulnerability_duration = 500

		# 设置武器攻击音效
		self.weapon_attack_sound = pygame.mixer.Sound('../audio/sword.wav')
		self.weapon_attack_sound.set_volume(0.4)


	def import_player_assets(self):
		character_path = '../graphics/player/'
		self.animations = {'up': [],'down': [],'left': [],'right': [],
			'right_idle':[],'left_idle':[],'up_idle':[],'down_idle':[],
			'right_attack':[],'left_attack':[],'up_attack':[],'down_attack':[]}

		for animation in self.animations.keys():
			full_path = character_path + animation
			self.animations[animation] = import_folder(full_path)

	def input(self):
		if not self.attacking:
			keys = pygame.key.get_pressed()

			if keys[pygame.K_UP] or keys[pygame.K_w]:
				self.direction.y = -1
				self.status = 'up'
			elif keys[pygame.K_DOWN] or keys[pygame.K_s]:
				self.direction.y = 1
				self.status = 'down'
			else:
				self.direction.y = 0

			if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
				self.direction.x = 1
				self.status = 'right'
			elif keys[pygame.K_LEFT] or keys[pygame.K_a]:
				self.direction.x = -1
				self.status = 'left'
			else:
				self.direction.x = 0
    
			# 普攻
			if keys[pygame.K_SPACE] or keys[pygame.K_j]:
				self.attacking = True
				self.attack_time = pygame.time.get_ticks()
				self.create_attack()
				self.weapon_attack_sound.play()

			# 魔法攻击
			if keys[pygame.K_LCTRL] or keys[pygame.K_k]:
				self.attacking = True
				self.attack_time = pygame.time.get_ticks()
				style = list(magic_data.keys())[self.magic_index]
				strength = list(magic_data.values())[self.magic_index]['strength']
				cost = list(magic_data.values())[self.magic_index]['cost']
				self.create_magic(style,strength,cost)
			
			# 武器切换
			if (keys[pygame.K_q] or keys[pygame.K_h]) and self.can_switch_weapon:
				self.can_switch_weapon = False
				self.weapon_switch_time = pygame.time.get_ticks()
				
				if self.weapon_index < len(list(weapon_data.keys())) - 1:
					self.weapon_index += 1
				else:
					self.weapon_index = 0
					
				self.weapon = list(weapon_data.keys())[self.weapon_index]

			# 魔法切换 +
			if (keys[pygame.K_e] or keys[pygame.K_i]) and self.can_switch_magic:
				self.can_switch_magic = False
				self.magic_switch_time = pygame.time.get_ticks()
				
				if self.magic_index < len(list(magic_data.keys())) - 1:
					self.magic_index += 1
				else:
					self.magic_index = 0

				self.magic = list(magic_data.keys())[self.magic_index]
      
	def animate(self):
		animation = self.animations[self.status]

		#设置帧索引，以便循环播放动画
		self.frame_index += self.animation_speed
		if self.frame_index >= len(animation):
			self.frame_index = 0

		self.image = animation[int(self.frame_index)]
		self.rect = self.image.get_rect(center = self.hitbox.center)

		if not self.vulnerable:
			alpha = self.wave_value()
			self.image.set_alpha(alpha)
		else:
			self.image.set_alpha(255)

  
	def get_status(self):
		if self.direction.x == 0 and self.direction.y == 0:
			if not 'idle' in self.status and not 'attack' in self.status:
				self.status = self.status + '_idle'

		if self.attacking:
			self.direction.x = 0
			self.direction.y = 0
			if not 'attack' in self.status:
				if 'idle' in self.status:
					self.status = self.status.replace('_idle','_attack')
				else:
					self.status = self.status + '_attack'
		else:
			if 'attack' in self.status:
				self.status = self.status.replace('_attack','')
    
	def cooldowns(self):
		current_time = pygame.time.get_ticks()

		if self.attacking:
			if current_time - self.attack_time >= self.attack_cooldown + weapon_data[self.weapon]['cooldown']:
				self.attacking = False
				self.destroy_attack()

		if not self.can_switch_weapon:
			if current_time - self.weapon_switch_time >= self.switch_duration_cooldown:
				self.can_switch_weapon = True	

		if not self.can_switch_magic:
			if current_time - self.magic_switch_time >= self.switch_duration_cooldown:
				self.can_switch_magic = True

		if not self.vulnerable:
			if current_time - self.hurt_time >= self.invulnerability_duration:
				self.vulnerable = True
    
	def get_full_weapon_damage(self):
		base_damage = self.stats['attack']
		weapon_damage = weapon_data[self.weapon]['damage']
		return base_damage + weapon_damage
	
	def get_full_magic_damage(self):
		base_damage = self.stats['magic']
		spell_damage = magic_data[self.magic]['strength']
		return base_damage + spell_damage
    
	def energy_recovery(self):
		if self.energy < self.stats['energy']:
			self.energy += 0.01 * self.stats['magic']
		else:
			self.energy = self.stats['energy']

	def update(self):
		self.input()
		self.cooldowns()
		self.get_status()
		self.animate()
		self.move(self.speed)
		self.energy_recovery()

	def get_value_by_index(self,index):
		return list(self.stats.values())[index]

	def get_cost_by_index(self,index):
		return list(self.upgrade_cost.values())[index]
